﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Cemit.PolyProto;

namespace Cemit.PolyServer.Game
{
    public class GameRoom
    {
        // 记录人物已接收到的帧数
        [System.Obsolete("效率过低，采用重连方案一次性重新发送当前游戏所有的帧信息")]
        private Dictionary<string, int> sendReplyRecords = new Dictionary<string, int>();

        private Dictionary<string, SendRecord> sendRecords;
        private ICollection<string> playerIds;

        //TODO: 需要用更高效率的能够命中缓存的数据结构
        private List<OperationFrame> operationFrames;
        private int current = 0;

        object sendingLock = new object();

        [System.Obsolete("效率过低，采用重连方案一次性重新发送当前游戏所有的帧信息")]
        public void Reply(string playerId, int maxIndex)
        {
            if (!sendReplyRecords.ContainsKey(playerId))
            {
                this.LogWarning("玩家不在该房间中！");
                return;
            }

            sendReplyRecords[playerId] = maxIndex;
        }

        public void AddOperation(string playerId, string operation)
        {
            lock (sendingLock)
            {
                lock (operationFrames[current])
                {
                    operationFrames[current].Add(playerId, operation);
                }
            }
        }

        /// <summary>开启房间，等待玩家加入</summary>
        public void Start(ICollection<string> playerIds)
        {
            sendRecords = new Dictionary<string, SendRecord>();
            foreach (var item in playerIds)
            {
                sendRecords.Add(item, new SendRecord { value = -1 });
            }

            this.playerIds = playerIds;

            current = 0;
            operationFrames = new List<OperationFrame>
            {
                new OperationFrame(current)
            };

            //向所有玩家转发消息
            Task.Run(async () => 
            {
                while (true)
                {
                    await Task.Delay(66);
                    int nowCurrent = current;

                    //Debug.Log(nowCurrent);

                    new Thread(() =>
                    {
                        lock (sendingLock)
                        {
                            current++;
                            operationFrames.Add(new OperationFrame(current));
                        }

                        foreach (var player in playerIds)
                        {
                            if (!GameServer.Instance.Players.Contains(player))
                            {
                                continue;
                            }

                            //发送操作帧给客户端
                            lock (sendRecords[player])
                            {
                                for (int i = sendRecords[player].value + 1; i <= nowCurrent; i++)
                                {
                                    GameServer.Instance.Players.GetPlayer(player)
                                        .Send(operationFrames[i].ToMsg());
                                    this.Log($"f: {i} to {player}");
                                }

                                sendRecords[player].value = nowCurrent;
                            }
                        }

                        // 效率过低，采用重连方案一次性重新发送当前游戏所有的帧信息
                        //foreach (var item in sendRecords)
                        //{
                        //    for (int i = item.Value; i < nowCurrent; i++)
                        //    {
                        //        if (GameServer.Instance.Players.Contains(item.Key))
                        //        {
                        //            GameServer.Instance.Players.GetPlayer(item.Key)
                        //                .Send(CreateOperationFrame(i));
                        //        }
                        //    }
                        //}

                    }).Start();
                }
               
            });
        }

        class SendRecord
        {
            public int value;
        }
    }
}
